package imageViewer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.util.Callback;

class ThumbnailsManager extends HBox {
	private int elementsPerPage = 0;
	private int actualPage = 1;
	private final Map<String, Thumbnail> thumbnailsByUrl = new HashMap();
	private final List<PhotoGallery> urls;
	private final HBox thumbnails;
	private Thumbnail active;
	private final Label left;
	private final Label right;

	public ThumbnailsManager(final List<PhotoGallery> urls,
			final Callback<PhotoGallery, Void> callback) {
		this.urls = new ArrayList(urls);

		this.thumbnails = new HBox();
		this.thumbnails.setAlignment(Pos.CENTER_LEFT);
		this.thumbnails.setSpacing(10.0D);

		this.left = new Label("<");
		this.right = new Label(">");
		this.left.getStyleClass().add("navigation");
		this.right.getStyleClass().add("navigation");

		this.left.setOnMouseClicked(new EventHandler() {
			public void handle(Event arg0) {
				if (ThumbnailsManager.this.actualPage > 1) {
					ThumbnailsManager.this
							.goToPage(ThumbnailsManager.this.actualPage - 1);
					ThumbnailsManager.access$010(ThumbnailsManager.this);
				}
			}
		});
		this.right.setOnMouseClicked(new EventHandler() {
			public void handle(MouseEvent arg0) {
				if (ThumbnailsManager.this.elementsPerPage
						* ThumbnailsManager.this.actualPage < urls.size()) {
					ThumbnailsManager.this
							.goToPage(ThumbnailsManager.this.actualPage + 1);
					ThumbnailsManager.access$008(ThumbnailsManager.this);
				}
			}
		});
		getChildren().addAll(
				new Node[] { this.left, this.thumbnails, this.right });

		getStyleClass().add("thumbnails");
		setAlignment(Pos.CENTER);
		setPadding(new Insets(10.0D));
		setSpacing(20.0D);

		double buttonsWidth = 120.0D;

		widthProperty().addListener(new ChangeListener() {
			public void changed(ObservableValue<? extends Number> arg0,
					Number oldValue, Number newValue) {
				ThumbnailsManager.this.goToPage(1);
				ThumbnailsManager.this.actualPage = 1;
				ThumbnailsManager.this.thumbnails.setMinWidth(-1.0D);

				ThumbnailsManager.this.calculateThumbnails(
						Double.valueOf(120.0D), oldValue, newValue);
			}
		});
		for (final PhotoGallery url : urls) {
			Thumbnail thumbnail = new Thumbnail(url.getThumbnailUrl());

			this.thumbnailsByUrl.put(url.getThumbnailUrl(), thumbnail);

			thumbnail.setOnMouseClicked(new EventHandler() {
				public void handle(Event arg0) {
					if ((ThumbnailsManager.this.active != null)
							&& (((Thumbnail) ThumbnailsManager.this.thumbnailsByUrl
									.get(url.getThumbnailUrl()))
									.equals(ThumbnailsManager.this.active))) {
						return;
					}

					callback.call(url);
				}
			});
		}
	}

	private void calculateThumbnails(Double buttonsWidth, Number oldValue,
			Number newValue) {
		boolean isFirstTime = oldValue.doubleValue() == 0.0D;

		if (oldValue.doubleValue() > newValue.doubleValue()) {
			if (newValue.doubleValue() < this.elementsPerPage * 60
					+ buttonsWidth.doubleValue()) {
				this.thumbnails.getChildren().remove(this.elementsPerPage - 1);
				this.elementsPerPage -= 1;
			}

		} else if ((isFirstTime)
				|| (oldValue.doubleValue() < newValue.doubleValue())) {
			boolean change = false;

			if (newValue.doubleValue() > (this.elementsPerPage + 1) * 60
					+ buttonsWidth.doubleValue()) {
				if (this.elementsPerPage < this.urls.size()) {
					Thumbnail thumbnail = (Thumbnail) this.thumbnailsByUrl
							.get(((PhotoGallery) this.urls
									.get(this.elementsPerPage++))
									.getThumbnailUrl());

					this.thumbnails.getChildren().add(thumbnail);
					if (isFirstTime) {
						thumbnail.init();
					}

					change = true;
				}
			}

			if ((isFirstTime) && (change))
				calculateThumbnails(buttonsWidth, oldValue, newValue);
		}
	}

	private void goToPage(int page) {
		this.thumbnails.setMinWidth(this.thumbnails.getWidth());

		this.thumbnails.getChildren().clear();
		for (int i = this.elementsPerPage * (page - 1); (i < this.elementsPerPage
				* page)
				&& (i < this.thumbnailsByUrl.size()); i++) {
			Thumbnail thumbnail = (Thumbnail) this.thumbnailsByUrl
					.get(((PhotoGallery) this.urls.get(i)).getThumbnailUrl());

			this.thumbnails.getChildren().add(thumbnail);
			thumbnail.init();
		}

		if (page == 1) {
			if (this.left.getStyleClass().remove("navigation")) {
				this.left.getStyleClass().add("navigation_disable");
			}
		} else if (this.left.getStyleClass().remove("navigation_disable")) {
			this.left.getStyleClass().add("navigation");
		}

		if (this.elementsPerPage * page >= this.thumbnailsByUrl.size()) {
			if (this.right.getStyleClass().remove("navigation")) {
				this.right.getStyleClass().add("navigation_disable");
			}
		} else if (this.right.getStyleClass().remove("navigation_disable"))
			this.right.getStyleClass().add("navigation");
	}

	public void updateThumbnail(String url, int position) {
		if (this.active != null) {
			this.active.getStyleClass().remove("active");
		}
		this.active = ((Thumbnail) this.thumbnailsByUrl.get(url));
		this.active.getStyleClass().add("active");

		int max = this.actualPage * this.elementsPerPage;
		int min = (this.actualPage - 1) * this.elementsPerPage;

		if ((position <= min) || (position > max)) {
			if (position > max) {
				if (position > (this.actualPage + 1) * this.elementsPerPage) {
					int lastPage = position / this.elementsPerPage
							+ (position % this.elementsPerPage == 0 ? 0 : 1);

					goToPage(lastPage);
					this.actualPage = lastPage;
				} else {
					goToPage(this.actualPage + 1);
					this.actualPage += 1;
				}
			} else if (position <= min) {
				if (position == 1) {
					goToPage(1);
					this.actualPage = 1;
				} else {
					goToPage(this.actualPage - 1);
					this.actualPage -= 1;
				}
			}
		}
	}
}